// PlayerKernel.h

// Jadro hraca, zakladne funkcie pre jeho funkcionalitu

#ifndef PLAYERKERNEL_H
#define PLAYERKERNEL_H

//#include "Player/Interfaces/Synchronization.h"
#include "Player/Interfaces/Memory.h"
//#include "Player/World/World.h"
//#include "Common/Module.h"
#include "Common/Main.h"

struct FEEDBACK_DATA;

#define BALL_HISTORY_COUNT 7

// Jadro hraca so synchronizaciou a rozhodovanim
class PlayerKernel : public Module, public SynchronizationInterface, public MemoryInterface
{
	// Sem sa ukladaju vsetky vykonane prikazy. Potom sa aplikuju tieto prikazy na model sveta,
	// tak aby odrazal, to co hrac vykonal.
	FEEDBACK_DATA* feedback;

	// Pocet spracovanych prikazov
	COMMAND_COUNTS* counts;

	// Synchronizacia
	SynchroMode synchMode;
	SynchroMode nextSynchMode;
	bool decisionWasMade;

protected:	
	// Model sveta
	World* world;
	
	// Model pohybu lopty (historia[N] + aktualny stav[1] + predikcia[N])
	Ball* ballStates[BALL_HISTORY_COUNT];
	
	// Index bunky, kde je ulozena aktualna informacia o lopte
	int nActualBallStateIndex;

	// Posledna informacia o skutocnej videnej lopte zo servera
	Ball* lastValidBallInfo;
	
	// Cyklus kedy hrac skutocne videl loptu
	int nLastValidBallTime;

	// Funkcia pre odstranenie informacii o lopte do nSteps cyklov
	void ClearPredictedBallStates(int nSteps);
	// Funkcia pre predpovedanie informacii o lopte v nasledujucich nSteps cykloch
	void PredictBallStates(Ball* actBallInfo, int nSteps);

	// Pozicie, na ktore sa hrac vracia, ked nevie, kde je lopta, alebo uz nie je potrebny v danej situacii.
	Point homePositions[11];

	Point umbrellaPositions[4];

	// Posledne sense_body a posledna vizualna informacia
	const SENSE_BODY* lastSb;
	const VISUAL_INFO* lastVi;
	
	int lastSbTime;
	int lastViTime;

	// Rozhodovanie sa
	virtual void Act()
	{
	
	}
	
public:
	// Strana hraca
	RealSide myside;
	
	// Konstruktor
	PlayerKernel(const char* name = "PlayerKernel", const char* desc = "PlayerKernel module");
	
	// Destruktor
	virtual ~PlayerKernel();

	// Implementacia rozhrania
	virtual Interface* GetInterface(int iTask) const;

	// Vracia pointer na model sveta
	virtual World* GetWorld() const
	{ 
		return world;
	}

	// Funkcie k synchroznizacnemu modu	
	virtual SynchroMode GetCurrentSynchMode() const
	{
		return synchMode;
	}
	virtual SynchroMode GetNextSynchMode() const
	{
		return nextSynchMode;
	}
	virtual void SetNextSynchMode(SynchroMode mode)
	{
		nextSynchMode = mode;
	}

	// Vnimanie a model sveta
	
	// Pri prichode spravy hear
	virtual void OnHear(int time, float direction, bool ourTeam, int uniform, const char* msg);
	// Pri zmene herneho modu
	virtual void OnChangeMode(int time, PlayMode mode);
	// Pri zmene typu hraca
	virtual void OnChangePlayerType(int uniform, int type);
	// Pri prichode spravy init
	virtual void OnInit(RealSide realSide, int uniform, PlayMode mode);
	// Handler pre informacie o heterogennych typoch hracov
	virtual void OnPlayerParam(const PLAYER_PARAMS* params);
	// Handler pre informacie o jednom heterogennom (alebo normalnom) type hraca
	virtual void OnPlayerType(int id, const PLAYER_TYPE* type);
	// Pri prichode spravy s informaciou o skore
	virtual void OnScore(int time, int our, int their);
	// Pri prichode zrakovej spravy see
	virtual void OnSee(const VISUAL_INFO*);
	// Pri prichode spravy sense_body
	virtual void OnSenseBody(const SENSE_BODY*);
	// Handler pre zmenu parametrov servera
	virtual void OnServerParam(const SERVER_PARAMS* params);
	
	virtual void OnFreeform(const char* msg);
//  virtual void OnSetParameterUseNN(const char* msg);	
	
	// Handlery pre ulozenie posielanych prikazov na server
	virtual void OnExecDash(float power);
	virtual void OnExecKick(float power, float direction);
	virtual void OnExecNeck(int angle);
	virtual void OnExecTurn(float moment);
};

// Struktura pre ulozenie vykonanych prikazov
struct FEEDBACK_DATA
{
	float lastPower;
	float lastTurn;
	int lastNeck;
	float lastKickPower;
	float lastKickDir;
};

#endif // PLAYERKERNEL_H
